home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/python
- # -*- coding: UTF-8 -*-
-
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License along
- # with this program; if not, write to the Free Software Foundation, Inc.,
- # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
- """Restricted Modules Manager.
-
- Usage:
- --update Update the restricted modules list
- --check Check for newly used restricted modules
- --enable MODULE Enable the named module
- --disable MODULE Disable the named module
- --check-composite Check if there is a graphics driver available that supports
- composite and offer to enable it
-
- Without arguments, immediately loads the restricted modules manager
- window.
- """
-
- __copyright__ = "Copyright © 2007 Canonical Ltd."
- __author__ = "Scott James Remnant <scott@ubuntu.com>"
-
-
- import os
- import sys
- import gettext
- from optparse import OptionParser
-
- import pygtk
- pygtk.require("2.0")
-
- import gobject
- import gtk
- import gtk.glade
- import pynotify
-
- import RestrictedManager
- from RestrictedManager.core import *
-
- from gettext import gettext as _
-
- class ManagerWindow(object):
- def __init__(self, xml, handlers):
- self.xml = xml
-
- gtk.window_set_default_icon_name("restricted-manager")
- self.dialog = self.xml.get_widget("dialog_manager")
- self.dialog.connect("delete_event", self.on_dialog_delete_event)
-
- self.treeview = self.xml.get_widget("treeview_drivers")
- self.treeview.get_selection().set_mode(gtk.SELECTION_NONE)
-
- text_renderer = gtk.CellRendererText()
- col1 = gtk.TreeViewColumn(_("Driver"))
- col1.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- col1.set_expand(True)
- col1.pack_start(text_renderer, True)
- col1.set_attributes(text_renderer, text=3)
- self.treeview.append_column(col1)
-
- toggle_renderer = gtk.CellRendererToggle()
- toggle_renderer.set_property("activatable", True)
- toggle_renderer.connect("toggled", self.on_renderer_toggled)
- col2 = gtk.TreeViewColumn(_("Enabled"))
- col2.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- col2.set_expand(False)
- col2.pack_start(toggle_renderer, True)
- col2.set_attributes(toggle_renderer, active=4)
- self.treeview.append_column(col2)
-
- pixbuf_renderer = gtk.CellRendererPixbuf()
- text_renderer = gtk.CellRendererText()
- col3 = gtk.TreeViewColumn(_("Status"))
- col3.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- col3.set_expand(False)
- col3.pack_start(pixbuf_renderer, False)
- col3.pack_end(text_renderer, True)
- col3.set_attributes(pixbuf_renderer, pixbuf=5)
- col3.set_attributes(text_renderer, text=6)
- self.treeview.append_column(col3)
-
- self.button_close = self.xml.get_widget("button_close")
- self.button_close.connect("clicked", self.on_button_close_clicked)
-
- self.handlers = handlers
- self.reset_model()
-
- # to remove the selection outline around the first item of the tree
- self.treeview.grab_focus()
-
- self.dialog.show()
-
- def reset_model(self):
- self.model = gtk.ListStore(gobject.TYPE_PYOBJECT,
- gobject.TYPE_PYOBJECT,
- gobject.TYPE_PYOBJECT,
- str, bool, gtk.gdk.Pixbuf, str)
-
- theme = gtk.icon_theme_get_default()
- handlers = sorted(self.handlers.values(), key=lambda x: x.description)
- for handler in handlers:
- is_enabled = handler.is_enabled()
- is_loaded = handler.is_loaded()
- if (is_enabled != is_loaded) and handler.is_changed():
- status, icon = _("Needs computer restart"), "reboot-notifier"
- elif is_loaded:
- status, icon = _("In use"), gtk.STOCK_YES
- else:
- status, icon = _("Not in use"), gtk.STOCK_NO
- try:
- pixbuf = theme.load_icon(icon, 16, gtk.ICON_LOOKUP_USE_BUILTIN)
- except:
- # do not fail if icon is not found, just create a 1px pixbuf
- pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, 1, 1)
- self.model.append([ handler, is_enabled, is_loaded,
- handler.description, is_enabled, pixbuf,
- status ])
-
- self.treeview.set_model(self.model)
-
- def on_dialog_delete_event(self, *args):
- gtk.main_quit()
-
- def on_renderer_toggled(self, widget, path, *args):
- self.action(path)
-
- def action(self, path):
- handler = self.model[path][0]
- is_enabled = self.model[path][1]
- is_loaded = self.model[path][2]
-
- ch = handler.can_change()
-
- if not ch:
- dlg = ConfirmDialog(self.xml, handler, is_enabled, self.dialog)
- if dlg.run() != gtk.RESPONSE_OK:
- return
-
- self.treeview.set_sensitive(False)
- if is_enabled:
- handler.disable()
-
- if handler.is_loaded():
- notify_reboot_required()
- else:
- handler.enable()
- self.treeview.set_sensitive(True)
- else:
- md = gtk.MessageDialog(self.dialog, type=gtk.MESSAGE_ERROR,
- buttons=gtk.BUTTONS_CLOSE, message_format=ch)
- md.run()
- md.hide()
- return
-
- self.reset_model()
- self.treeview.grab_focus()
-
- def on_button_close_clicked(self, *args):
- gtk.main_quit()
-
-
- class ConfirmDialog(object):
- def __init__(self, xml, handler, is_enabled, parent=None):
- self.xml = xml
- self.handler = handler
- self.is_enabled = is_enabled
-
- self.dialog = self.xml.get_widget("dialog_confirm")
- self.dialog.set_title("")
- if parent is not None:
- self.dialog.set_transient_for(parent)
- self.xml.get_widget("button_cancel").grab_focus()
-
- if self.is_enabled:
- frob = _("Disable the driver?")
- self.xml.get_widget("label_ok").set_label(_("_Disable Driver"))
- else:
- frob = _("Enable the driver?")
- self.xml.get_widget("label_ok").set_label(_("_Enable Driver"))
-
- label = self.xml.get_widget("label_text")
- label.set_label("<span weight=\"bold\" size=\"larger\">"
- "%s"
- "</span>\n\n"
- "<span weight=\"bold\">%s</span>\n\n"
- "%s" % (frob, handler.description, handler.rationale))
-
- def run(self):
- ret = self.dialog.run()
- self.dialog.hide()
- return ret
-
-
- class Notification(object):
- def __init__(self):
- self.trayicon = gtk.status_icon_new_from_icon_name("restricted-manager")
- self.trayicon.connect("activate", self.open_manager)
- self.trayicon.set_tooltip(_("New Restricted Drivers in use"))
-
- gobject.timeout_add (500, self.show_notify)
-
- def show_notify(self):
- pynotify.init("restricted-manager")
-
- notify = pynotify.Notification(_("New restricted drivers in use"),
- "<span weight=\"bold\">%s</span>\n\n%s" % (
- _("In order for this computer to function properly, Ubuntu is "
- "using driver software that cannot be supported"),
- _("Click on this icon to open the Restricted Drivers control "
- "panel.")), "restricted-manager")
- notify.set_urgency(pynotify.URGENCY_NORMAL)
- notify.attach_to_status_icon(self.trayicon)
- notify.show()
-
- def open_manager(self, *args):
- runme_as_root()
-
- def runme_as_root(extra_argv = []):
- """Execute myself through gksu."""
-
- argv = ["gksu", "-D", _("Restricted Drivers manager"),
- "--", sys.argv[0]] + extra_argv
- os.execvp("gksu", argv)
-
- def gtk_idle():
- while gtk.events_pending():
- gtk.main_iteration(False)
-
- def main(args, opts):
- try:
- xml = gtk.glade.XML("/usr/share/restricted-manager/manager.glade")
- except RuntimeError:
- glade_filename = os.path.join(os.path.dirname(RestrictedManager.__file__),
- "manager.glade")
- xml = gtk.glade.XML(glade_filename)
-
- RestrictedManager.core.package_install_idle_function = gtk_idle
-
- # set the title label here instead of the glade file, so that it can be
- # translated more easily
- xml.get_widget("label_heading").set_label('<span weight="bold">%s</span>\n\n%s' % (
- _("In order for this computer to function properly, Ubuntu may be using driver software that cannot be supported."),
- _("Because the software is proprietary, it cannot easily be changed to fix any future problems.")
- ))
-
- if not am_admin():
- print >>sys.stderr, _("Must be run as member of admin group")
- return 1
-
- if opts.update:
- load_restricted_list(force=True)
- elif opts.list:
- handlers = get_handlers()
- for handler in handlers.values():
- print handler.name
- elif opts.check:
- handlers = get_handlers()
- used = load_used_list()
- new = []
-
- for handler in handlers.values():
- if handler.name in used:
- continue
- elif handler.is_loaded():
- new.append(handler.name)
-
- if new:
- used.extend(new)
- save_used_list(used)
-
- Notification()
- gtk.main()
- elif opts.check_composite:
- handlers = get_handlers()
- try:
- handler = handlers["nvidia"]
- if handler.is_enabled():
- print "nvidia restricted driver is already enabled"
- return 1
- except KeyError:
- print "nvidia hardware not available"
- return 1
-
- runme_as_root(["--enable", "nvidia"])
-
- elif os.getuid() > 0:
- print >>sys.stderr, _("Must be run as root")
- return 1
- elif opts.enable:
- handlers = get_handlers()
- try:
- handler = handlers[opts.enable]
- except KeyError:
- print >>sys.stderr, _("Unknown module: %s") % opts.enable
- return 1
-
- if handler.is_enabled():
- print >>sys.stderr, _("%s is already enabled") % opts.enable
- return 1
-
- ch = handler.can_change()
- if ch:
- md = gtk.MessageDialog(type=gtk.MESSAGE_ERROR,
- buttons=gtk.BUTTONS_CLOSE, message_format=ch)
- md.run()
- md.hide()
- return
-
- if ConfirmDialog(xml, handler, False).run() != gtk.RESPONSE_OK:
- return
-
- handler.enable()
- elif opts.disable:
- handlers = get_handlers()
- try:
- handler = handlers[opts.disable]
- except KeyError:
- print >>sys.stderr, "Unknown module: %s" % opts.disable
- return 1
-
- if not handler.is_enabled():
- print >>sys.stderr, "%s is already disabled" % opts.disable
- return 1
-
- ch = handler.can_change()
- if ch:
- md = gtk.MessageDialog(type=gtk.MESSAGE_ERROR,
- buttons=gtk.BUTTONS_CLOSE, message_format=ch)
- md.run()
- md.hide()
- return
-
- if ConfirmDialog(xml, handler, True).run() != gtk.RESPONSE_OK:
- return
-
- handler.disable()
- else:
- # check whether we have restricted modules installed
- lrm = "linux-restricted-modules-" + os.uname()[2]
- if not DefaultHandler.package_installed(lrm):
- md = gtk.MessageDialog(type=gtk.MESSAGE_ERROR,
- buttons=gtk.BUTTONS_CLOSE, message_format=_(
- "You need to install the package\n\n %s\n\nfor this program to work.") % lrm)
- md.run()
- md.hide()
- return 0
-
- handlers = get_handlers()
-
- if not handlers:
- md = gtk.MessageDialog(type=gtk.MESSAGE_INFO,
- buttons=gtk.BUTTONS_CLOSE, message_format=_(
- "Your hardware does not need any restricted drivers."))
- md.run()
- md.hide()
- return 0
-
- ManagerWindow(xml, handlers)
- RestrictedManager.core.package_install_xid = \
- xml.get_widget("dialog_manager").window.xid
-
- gtk.main()
-
- def get_opt_args():
- parser = OptionParser()
- parser.add_option ("-u", "--update", action="store_true",
- dest="update", default=False,
- help=_("Update restricted modules list"))
- parser.add_option ("-c", "--check", action="store_true",
- dest="check", default=False,
- help=_("Check for newly used restricted modules"))
- parser.add_option ("-l", "--list", action="store_true",
- dest="list", default=False,
- help=_("List available restricted modules"))
- parser.add_option ("-C", "--check-composite", action="store_true",
- dest="check_composite", default=False,
- help=_("Check if there is a graphics driver available that supports composite and offer to enable it"))
- parser.add_option ("-e", "--enable", type="string",
- dest="enable", default="", metavar="MODULE",
- help=_("Enable the named module"))
- parser.add_option ("-d", "--disable", type="string",
- dest="disable", default="", metavar="MODULE",
- help=_("Disable the named module"))
- return parser.parse_args()
-
- if __name__ == "__main__":
- gettext.textdomain("restricted-manager")
- gtk.glade.textdomain("restricted-manager")
- #gettext.bindtextdomain("restricted-manager", "po/mo")
- (opts, args) = get_opt_args()
-
- sys.exit(main(args, opts))
-